package com.navi.job;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.navi.service.impl.RabbitService;
import com.navi.util.JacksonUtil;
import com.navi.util.LogUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.GetResponse;
import com.rabbitmq.http.client.domain.QueueInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;

import static com.navi.constant.GenericDef.*;
import static java.util.stream.Collectors.toList;

/**
 * Created by ghost on 2018/10/1.
 */
@Slf4j
@Service
public class HmsLoaderInfoService {

    @Autowired
    private RabbitService rabbitService;

    public String getQueuesNameList(String queueName) {
        String queueNames = null;

        //PDS GLASS SUMMARY
        if ("ASUMMARY_P1".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_array_"))
                    .filter(q -> A_SUMMARY_P1.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("ASUMMARY_P2".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_array_"))
                    .filter(q -> A_SUMMARY_P2.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("ASUMMARY_P3".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_array_"))
                    .filter(q -> A_SUMMARY_P3.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("ASUMMARY_P4".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_array_"))
                    .filter(q -> A_SUMMARY_P4.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("ASUMMARY_P5".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_array_"))
                    .filter(q -> A_SUMMARY_P5.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("ASUMMARY_P6".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_array_"))
                    .filter(q -> A_SUMMARY_P6.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("FSUMMARY_P1".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_cf_"))
                    .filter(q -> F_SUMMARY_P1.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("FSUMMARY_P2".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_cf_"))
                    .filter(q -> F_SUMMARY_P2.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("FSUMMARY_P3".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_cf_"))
                    .filter(q -> F_SUMMARY_P3.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("FSUMMARY_P4".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_cf_"))
                    .filter(q -> F_SUMMARY_P4.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("CSUMMARY_P1".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_cell_"))
                    .filter(q -> C_SUMMARY_P1.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("CSUMMARY_P2".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_cell_"))
                    .filter(q -> C_SUMMARY_P2.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("CSUMMARY_P3".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_cell_"))
                    .filter(q -> C_SUMMARY_P3.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("CSUMMARY_P4".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_cell_"))
                    .filter(q -> C_SUMMARY_P4.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("C2SUMMARY_P1".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_cell2_"))
                    .filter(q -> C2_SUMMARY_P1.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("C2SUMMARY_P2".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("pds") && q.getName().contains("_cell2_"))
                    .filter(q -> C2_SUMMARY_P2.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("ASUMMARY_I1".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_array_"))
                    .filter(q -> A_SUMMARY_I1.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("ASUMMARY_I2".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_array_"))
                    .filter(q -> A_SUMMARY_I2.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("ASUMMARY_I3".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_array_"))
                    .filter(q -> A_SUMMARY_I3.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("ASUMMARY_I4".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_array_"))
                    .filter(q -> A_SUMMARY_I4.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("ASUMMARY_I5".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_array_"))
                    .filter(q -> A_SUMMARY_I5.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("FSUMMARY_I1".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_cf_"))
                    .filter(q -> F_SUMMARY_I1.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("FSUMMARY_I2".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_cf_"))
                    .filter(q -> F_SUMMARY_I2.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("FSUMMARY_I3".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_cf_"))
                    .filter(q -> F_SUMMARY_I3.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("CSUMMARY_I1".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_cell_"))
                    .filter(q -> C_SUMMARY_I1.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("CSUMMARY_I2".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_cell_"))
                    .filter(q -> C_SUMMARY_I2.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("C2SUMMARY_I1".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_cell2_"))
                    .filter(q -> C2_SUMMARY_I1.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("C2SUMMARY_I2".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_cell2_"))
                    .filter(q -> C2_SUMMARY_I2.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("C2SUMMARY_I3".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_cell2_"))
                    .filter(q -> C2_SUMMARY_I3.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        } else if ("C2SUMMARY_I4".equals(queueName)) {
            queueNames = rabbitService.getQueueInfo().stream()
                    .filter(q -> q.getName().startsWith("eda_") && q.getName().contains("mds") && q.getName().contains("_cell2_"))
                    .filter(q -> C2_SUMMARY_I4.contains(q.getName().substring(q.getName().length() - 4, q.getName().length())))
                    .map(QueueInfo::getName).collect(Collectors.joining(","));
        }

        return queueNames;
    }


    //从通道获取数据
    public List<String> getMessageFromQueue(Channel channel, String queueName, Map<GetResponse, String> responseMap) throws IOException {
        List<String> messageList = new ArrayList<>();
        while (true) {
            if (getMessage(channel, queueName, messageList, responseMap)) break;
        }
        return messageList;
    }

    //从通道获取数据
    public List<String> getMessageFromQueue(Channel channel, String queueName, int limit, Map<GetResponse, String> responseMap) throws IOException {
        List<String> messageList = new ArrayList<>();
        for (int i = 0; i < limit; i++) {
            if (getMessage(channel, queueName, messageList, responseMap)) {//失败了
                break;
            }
        }
        return messageList;
    }

    //从通道获取一笔数据
    public boolean getMessage(Channel channel, String queueName, List<String> messageList, Map<GetResponse, String> responseMap) throws IOException {
        final GetResponse getResponse = channel.basicGet(queueName, false);
        if (getResponse == null) return true;
        String message = new String(getResponse.getBody(), "utf-8");
        if (getResponse.getBody() == null) return true;


        if ("[]".equalsIgnoreCase(message) || message.indexOf("ope_tbl_name") < 0) {//如果为空json 或者 没有指定表名
            channel.basicAck(getResponse.getEnvelope().getDeliveryTag(), false);
        } else {
            if (!message.contains("defect_f_n")) {
                responseMap.put(getResponse, message);
                messageList.add(message);
                log.debug("message from [{}] , {} ", queueName, message);
            }
        }
        return false;
    }


    //处理Queue的数据，根据 ope_tbl_name 转换成 json 对象 or 数组
    public Map<String, List<JSONObject>> getMessageFromQueueThenGroupByTableName2Map(List<String> messageList,  Map<GetResponse, String> responseMap) throws Exception {
        List<JSONObject> jsonObject2List = new ArrayList<>();


        messageList.stream().collect(Collectors.toList()).forEach(message -> {
            if (StringUtils.startsWith(message, "{")) {
                JSONObject jsonObj = (JSONObject) JSONObject.parse(message);
                jsonObject2List.add(jsonObj);

            } else if (StringUtils.startsWith(message, "[")) {
                List<JSONObject> jsonObjList = JSONArray.parseArray(message).stream().map(obj -> (JSONObject) obj).collect(toList());
                jsonObject2List.addAll(jsonObjList);
            }
        });
        //todo 一个Q一张表时不需要处理，可以在forEach中计算
        return jsonObject2List.stream().collect(Collectors.groupingBy(jsonObj -> jsonObj.getString("ope_tbl_name")));
    }

    public void getSummaryMap(String qType, List<JSONObject> jsonObjectList, HashMap<String, List<JSONObject>> summaryMap) {
        switch (qType) {
            case "PDS":
                List<JSONObject> pdsGlassList = new ArrayList<>();
                List<JSONObject> pdsSummaryList = new ArrayList<>();

                jsonObjectList.forEach(glassSumResult -> {
                    JSONObject glass = glassSumResult.getJSONObject("part1");
                    JSONArray summary = glassSumResult.getJSONArray("part2");
                    pdsGlassList.add(glass);
                    if (!summary.isEmpty())
                        summary.forEach(e -> pdsSummaryList.add((JSONObject) JSONObject.parse(JacksonUtil.toJSONStr(e))));
                });
                summaryMap.put("pdsGlass", pdsGlassList);
                summaryMap.put("pdsSummary", pdsSummaryList);
                break;
            case "MDS":
                List<JSONObject> mdsGlassList = new ArrayList<>();
                List<JSONObject> mdsSummaryList = new ArrayList<>();
                List<JSONObject> mdsResultList = new ArrayList<>();

                jsonObjectList.forEach(glassSumResult -> {
                    JSONObject glass = glassSumResult.getJSONObject("part1");
                    JSONArray summary = glassSumResult.getJSONArray("part2");
                    JSONArray result = glassSumResult.getJSONArray("part3");
                    mdsGlassList.add(glass);
                    if (!summary.isEmpty())
                        summary.forEach(e -> mdsSummaryList.add((JSONObject) JSONObject.parse(JacksonUtil.toJSONStr(e))));
                    if (!result.isEmpty())
                        result.forEach(e -> mdsResultList.add((JSONObject) JSONObject.parse(JacksonUtil.toJSONStr(e))));
                });
                summaryMap.put("mdsGlass", mdsGlassList);
                summaryMap.put("mdsSummary", mdsSummaryList);
                summaryMap.put("mdsResult", mdsResultList);
                break;
        }

    }


}
